<!DOCTYPE html>
<html>
<head>
    <title>Cantilever Beam Static Analysis</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background-color: #f8f9fa;
        }
        canvas {
            border: 1px solid #dee2e6;
            background-color: white;
        }
    </style>
</head>
<body>
    <canvas id="beamCanvas" width="750" height="450"></canvas>
    <script>
        const canvas = document.getElementById('beamCanvas');
        const ctx = canvas.getContext('2d');

        // --- Drawing Parameters ---
        const scale = 55; // pixels per meter
        const originX = 100;
        const originY = 250;

        // --- Helper Function for Arrowheads ---
        function drawArrowhead(ctx, fromX, fromY, toX, toY, size) {
            const angle = Math.atan2(toY - fromY, toX - fromX);
            ctx.moveTo(toX, toY);
            ctx.lineTo(toX - size * Math.cos(angle - Math.PI / 7), toY - size * Math.sin(angle - Math.PI / 7));
            ctx.moveTo(toX, toY);
            ctx.lineTo(toX - size * Math.cos(angle + Math.PI / 7), toY - size * Math.sin(angle + Math.PI / 7));
        }

        // --- Main Drawing Function ---
        function drawBeamDiagram() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            ctx.save();
            ctx.translate(originX, originY);

            ctx.strokeStyle = 'black';
            ctx.fillStyle = 'black';

            // --- 1. Draw the Beam ---
            const beamLength = 10 * scale;
            ctx.lineWidth = 4;
            ctx.beginPath();
            ctx.moveTo(0, 0);
            ctx.lineTo(beamLength, 0);
            ctx.stroke();

            // --- 2. Draw the Fixed Support ---
            const wallX = beamLength;
            const wallHeight = 100;
            ctx.lineWidth = 3;
            ctx.beginPath();
            ctx.moveTo(wallX, -wallHeight / 2);
            ctx.lineTo(wallX, wallHeight / 2);
            ctx.stroke();
            // Hatching
            ctx.lineWidth = 1.5;
            for (let i = -wallHeight / 2; i <= wallHeight / 2; i += 12) {
                ctx.beginPath();
                ctx.moveTo(wallX, i);
                ctx.lineTo(wallX + 20, i - 20);
                ctx.stroke();
            }

            // --- 3. Draw Coordinate Axes ---
            ctx.lineWidth = 1.5;
            ctx.font = 'italic bold 20px Times New Roman';
            // y-axis
            ctx.beginPath();
            ctx.moveTo(40, 20);
            ctx.lineTo(-40, 20);
            drawArrowhead(ctx, 40, 20, -40, 20, 10);
            ctx.stroke();
            ctx.fillText('y', -45, 0);
            // x-axis at the wall
            ctx.beginPath();
            ctx.moveTo(wallX + 30, 30);
            ctx.lineTo(wallX + 30, -150);
            drawArrowhead(ctx, wallX + 30, 30, wallX + 30, -150, 10);
            ctx.stroke();
            ctx.fillText('x', wallX + 10, -140);


            // --- 4. Draw Distributed Load (q) ---
            const q_len = 3 * scale;
            const q_height = 40;
            ctx.lineWidth = 2;
            ctx.font = 'bold 20px Arial';
            // Box
            ctx.beginPath();
            ctx.strokeRect(0, -q_height, q_len, q_height);
            // Arrows inside box
            ctx.beginPath();
            for (let i = 1; i <= 4; i++) {
                let x_pos = i * q_len / 5;
                ctx.moveTo(x_pos, -q_height);
                ctx.lineTo(x_pos, -5);
                drawArrowhead(ctx, x_pos, -q_height, x_pos, -5, 10);
            }
            ctx.stroke();
            // Horizontal arrow and Label
            ctx.beginPath();
            ctx.moveTo(0, -q_height / 2);
            ctx.lineTo(-40, -q_height / 2);
            drawArrowhead(ctx, 0, -q_height / 2, -40, -q_height / 2, 10);
            ctx.stroke();
            ctx.fillText('q=3 kN/m', 10, -q_height - 15);

            // --- 5. Draw Couple at the free end (2 kN·m) ---
            ctx.lineWidth = 2;
            const m1_radius = 25;
            const m1_y = 50;
            ctx.beginPath();
            ctx.arc(-m1_radius, 0, m1_radius, -Math.PI/2, Math.PI/2);
            drawArrowhead(ctx, -m1_radius, -m1_radius, -m1_radius, -m1_radius, 10);
            ctx.stroke();
            ctx.fillText('2 kN·m', -30, m1_y + 30);


            // --- 6. Draw Forces at 6m mark ---
            const pos6m = 6 * scale;

            // 6a. Concentrated Couple (3 kN·m)
            ctx.lineWidth = 2;
            const couple_height = 40;
            ctx.beginPath();
            ctx.moveTo(pos6m, -couple_height);
            ctx.lineTo(pos6m, couple_height);
            // Top arrow (left)
            ctx.moveTo(pos6m, -couple_height);
            ctx.lineTo(pos6m - 40, -couple_height);
            drawArrowhead(ctx, pos6m, -couple_height, pos6m - 40, -couple_height, 10);
            // Bottom arrow (right)
            ctx.moveTo(pos6m, couple_height);
            ctx.lineTo(pos6m + 40, couple_height);
            drawArrowhead(ctx, pos6m, couple_height, pos6m + 40, couple_height, 10);
            ctx.stroke();
            ctx.fillText('3 kN·m', pos6m - 120, -50);

            // 6b. Concentrated Force (4 kN)
            ctx.lineWidth = 3;
            const force_len = 80;
            const angle_deg = 45;
            const angle_rad = angle_deg * Math.PI / 180;
            const start_fx = pos6m + force_len * Math.sin(angle_rad);
            const start_fy = -force_len * Math.cos(angle_rad);
            ctx.beginPath();
            ctx.moveTo(start_fx, start_fy);
            ctx.lineTo(pos6m, 0);
            drawArrowhead(ctx, start_fx, start_fy, pos6m, 0, 15);
            ctx.stroke();
            ctx.fillText('4 kN', start_fx + 10, start_fy);

            // Angle Indicator
            ctx.lineWidth = 1.5;
            const angle_pos_on_line = 0.4;
            const angle_origin_x = pos6m + (start_fx - pos6m) * angle_pos_on_line;
            const angle_origin_y = 0 + (start_fy - 0) * angle_pos_on_line;
            ctx.beginPath();
            ctx.moveTo(angle_origin_x, angle_origin_y);
            ctx.lineTo(angle_origin_x, angle_origin_y + 30);
            drawArrowhead(ctx, angle_origin_x, angle_origin_y, angle_origin_x, angle_origin_y + 30, 8);
            ctx.stroke();
            const arc_radius = 25;
            ctx.beginPath();
            ctx.arc(angle_origin_x, angle_origin_y, arc_radius, Math.PI / 2, Math.PI / 2 - angle_rad, true);
            ctx.stroke();
            ctx.font = 'bold 20px Arial';
            ctx.fillText(angle_deg + '°', angle_origin_x + arc_radius + 5, angle_origin_y + 20);

            // --- 7. Draw Dimensions ---
            const dimY = 70;
            ctx.lineWidth = 1.5;
            ctx.font = 'bold 18px Arial';
            
            function drawDim(x_start, length, label) {
                const x_end = x_start + length;
                const x_mid = x_start + length / 2;
                
                // Ticks on beam
                ctx.beginPath();
                ctx.moveTo(x_start, -8);
                ctx.lineTo(x_start, 8);
                ctx.moveTo(x_end, -8);
                ctx.lineTo(x_end, 8);
                ctx.stroke();
                
                // Horizontal lines with arrows
                ctx.beginPath();
                ctx.moveTo(x_mid - 25, dimY);
                ctx.lineTo(x_start, dimY);
                drawArrowhead(ctx, x_mid, dimY, x_start, dimY, 10);
                
                ctx.moveTo(x_mid + 25, dimY);
                ctx.lineTo(x_end, dimY);
                drawArrowhead(ctx, x_mid, dimY, x_end, dimY, 10);
                ctx.stroke();
                
                // Label
                ctx.fillText(label, x_mid - 18, dimY + 6);
            }

            drawDim(0, 3 * scale, '3 m');
            drawDim(3 * scale, 3 * scale, '3 m');
            drawDim(6 * scale, 4 * scale, '4 m');
            
            ctx.restore();
        }

        drawBeamDiagram();
    </script>
</body>
</html>